#include <iostream>

/*
const 修饰的变量不能再作为左值，初始化完成后，不能修改

const修饰函数参数，表示该参数不能被修改
const修饰函数返回值，表示该返回值不能被修改，一般用于与指针或引用结合
const修饰函数，表示该函数不会修改类的成员变量，该类型的常实例对象可以调用该方法（只读方法）
常实例对象需要有明确的默认构造函数：
常实例对象在创建后不能被修改，因此必须在创建时进行初始化。如果没有明确的默认构造函数，编译器无法保证对象在创建时能够正确初始化，因此要求程序员显式定义默认构造函数以确保对象的正确初始化。
*/

/*
constexpr 变量可以在编译期初始化
consteval 变量必须在编译期初始化
*/

class Foo {
public:
  Foo() : _a(0) {} // 常实例对象需要类有明确的默认构造函数
  int a() const { return _a; }
  int a2() { return _a; }

private:
  int _a;
};
int main() {
  Foo f;
  const Foo f2;
  std::cout << f.a() << std::endl;
  std::cout << f2.a() << std::endl;

  f.a2();
  // f2.a2(); // 'this' argument to member function 'a2' has type 'const Foo', but function is not marked const
}